package dbmanager

import (
	"gitee.com/night-tc/gobige/global"
	"gitee.com/night-tc/gobige/logger"
	"gitee.com/night-tc/gobige/msgdef/protomsg"
)

/*
OtherSrvMsgProc.go 文件用于处理从DB服务器发送到其他服务器的消息。
该文件定义了OtherSrvMsgProc结构体及其相关方法，用于接收和处理来自DB服务器的数据，
并将数据转发给其他服务器。
*/

// NewOtherSrvMsgProc 创建一个新的OtherSrvMsgProc实例。
// pmd: 玩家接口，用于与玩家相关的操作。
func NewOtherSrvMsgProc(pmd IPlayer) *OtherSrvMsgProc {
	return &OtherSrvMsgProc{
		player: pmd,
		tmpli:  make(map[uint64]map[string]IDataBaseModel),
	}
}

// 一次收发消息的数据量
const DataList_Count = 50

// OtherSrvMsgProc 结构体用于处理从DB服务器发送到其他服务器的消息。
type OtherSrvMsgProc struct {
	player IPlayer
	tmpli  map[uint64]map[string]IDataBaseModel
}

// MsgProc_DBGetPlayerInfoAck 处理从DB服务器发送的玩家信息确认消息。
// msg: 包含玩家信息的消息。
func (this *OtherSrvMsgProc) MsgProc_DBGetPlayerInfoAck(msg *protomsg.DBGetPlayerInfoAck) {
	mg := GetDBSingleton()
	var tli map[string]IDataBaseModel
	ok := false
	if tli, ok = this.tmpli[msg.BackKey]; !ok {
		tli = make(map[string]IDataBaseModel)
	}
	for i := range msg.DBList {
		md := mg.GetModelByKeyName(msg.DBList[i].KeyName)
		_ = md.Unmarshal(msg.DBList[i].MsgContent)
		tli[md.KeyName()] = md
	}
	this.tmpli[msg.BackKey] = tli
}

// MsgProc_DBGetPlayerInfoEndAck 处理从DB服务器发送的玩家信息结束确认消息。
// msg: 包含结束确认信息的消息。
func (this *OtherSrvMsgProc) MsgProc_DBGetPlayerInfoEndAck(msg *protomsg.DBGetPlayerInfoEndAck) {
	if f := this.player.PopBackFunc(msg.BackKey); f != nil {
		if tli, ok := this.tmpli[msg.BackKey]; ok {
			f(tli)
			delete(this.tmpli, msg.BackKey)
		} else {
			f(make(map[string]IDataBaseModel))
		}
	}
}

// MsgProc_OtherGetPlayerInfoReq 处理从其他服务器发送的获取玩家信息请求。
// msg: 包含请求信息的消息。
func (this *OtherSrvMsgProc) MsgProc_OtherGetPlayerInfoReq(msg *protomsg.OtherGetPlayerInfoReq) {
	dbli := make([]*protomsg.DBDataModel, 0, 100)
	for _, srvname := range msg.SrvNames {
		md, ok := this.player.GetServiceModel(srvname)
		if !ok {
			logger.Warnf("OtherSrvMsgProc.MsgProc_OtherGetPlayerInfoReq: %s not found", srvname)
			continue
		}
		dbli = append(dbli, md.GetDataArgs().GetMsgByAllData(nil).DBList...)
	}
	for l := len(dbli); l > 0; l = len(dbli) {
		ack := new(protomsg.DBGetPlayerInfoAck)
		ack.BackKey = msg.BackKey
		if l > DataList_Count {
			ack.DBList = dbli[:DataList_Count]
			dbli = dbli[DataList_Count:]
		} else {
			ack.DBList = dbli
			dbli = dbli[:0]
		}
		_ = global.GetSrvInst().PostMsgToEntity(msg.SrvID, msg.SpaceID, msg.EntityID, ack)
	}
	// 全部发完，给他服发送结束通知
	endack := new(protomsg.DBGetPlayerInfoEndAck)
	endack.BackKey = msg.BackKey
	_ = global.GetSrvInst().PostMsgToEntity(msg.SrvID, msg.SpaceID, msg.EntityID, endack)
}

// MsgProc_OtherUpUserDatasRet 处理从其他服务器发送的用户数据更新返回消息。
// msg: 包含更新返回信息的消息。
func (this *OtherSrvMsgProc) MsgProc_OtherUpUserDatasRet(msg *protomsg.OtherUpUserDatasRet) {
	v, ok := this.player.GetServiceModel(msg.ServiceName)
	if !ok {
		return
	}
	v.OtherData(msg.Data)
}